package monitor;

import beans.OperationsRemote;
import co.edu.unal.satacredito.database.connection.EventLogDatastoreFactory;
import co.edu.unal.satacredito.database.connection.MachineDatastoreFactory;
import co.edu.unal.satacredito.database.connection.TransactionDatastoreFactory;
import co.edu.unal.satacredito.database.dao.EventLogMongoDao;
import co.edu.unal.satacredito.database.dao.MachineMongoDao;
import co.edu.unal.satacredito.database.dao.TransactionMongoDao;
import co.edu.unal.satacredito.database.entity.Machine;
import co.edu.unal.satacredito.database.entity.Transaction;
import co.edu.unal.satacredito.database.entity.exceptions.NonexistentEntityException;
import co.edu.unal.satacredito.database.exception.UnreachableHostException;
import com.google.code.morphia.Datastore;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 *
 * @author migueldiaz
 * @author laarguelless
 */
public final class Daemon {

    private static final String SATACREDITO_PATH = "SATACREDITO_PATH";
    private static final String FILE_PATH = "config/timeout";
    private static final String FILE_NAME = "timeout";
    private MachineMongoDao instanceMachine;
    private EventLogMongoDao instanceLog;
    private TransactionMongoDao instanceTrans;
    private Long TIME_OUT;
    private List<Transaction> tasklist = null;
    private List<Machine> avMachines = null;
    private String machinesEJBip = "5.185.48.148";

    public Daemon() throws UnknownHostException {


        Datastore ds1;
        Datastore ds2;
        Datastore ds3;
        ds1 = EventLogDatastoreFactory.createDatastore();
        this.instanceLog = new EventLogMongoDao(ds1);
        ds2 = MachineDatastoreFactory.createDatastore();
        this.instanceMachine = new MachineMongoDao(ds2);
        ds3 = TransactionDatastoreFactory.createDatastore();
        this.instanceTrans = new TransactionMongoDao(ds3);

        try {
            getTimeOut();
        } catch (Exception ex) {
            Logger.getLogger(Daemon.class.getName()).log(Level.SEVERE, null, ex);
        }

        callThreads();

    }

    public void getTimeOut() throws FileNotFoundException, IOException {
        Properties properties = new Properties();
        properties.load(new FileInputStream(System.getenv(SATACREDITO_PATH) + "/"
                + FILE_PATH + "/" + FILE_NAME + ".properties"));

        this.TIME_OUT = new Long(properties.getProperty("TIME_OUT"));
    }

    public final void callThreads() {
        new AbortedProcesses(TIME_OUT, instanceLog, this).start();

    }

    public List<String> getAvailableMachines() throws IOException, NamingException {

        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.enterprise.naming.SerialInitContextFactory");
        properties.setProperty("org.omg.CORBA.ORBInitialHost", machinesEJBip);
        properties.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

        InitialContext context = new InitialContext(properties);
        OperationsRemote operations = (OperationsRemote) context.lookup("beans.OperationsRemote");

        List<String> avalaibleMachines = operations.ipsList();
        return avalaibleMachines;
    }

    public void getTasksToComplete() throws UnreachableHostException {
        this.tasklist = instanceTrans.findNotValidatedYet();
    }

    public Boolean ping(String ip) throws IOException {
        Socket socket = null;
        boolean reachable = false;
        try {
            socket = new Socket(ip, 8080);
            reachable = true;
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                }
            }
            return reachable;
        }
    }

    public void assignWork() throws UnreachableHostException, IOException, NamingException {
        do {
            getTasksToComplete();
            Machine mach = null;
            List<String> machines = getAvailableMachines();
            for (String machine : machines) {
                try {
                    mach = instanceMachine.findByIP(machine);
                    avMachines.add(mach);
                } catch (NonexistentEntityException ex) {
                }
            }            
            
            if (!avMachines.isEmpty() && !tasklist.isEmpty()) {
                int numberProcess = tasklist.size()/avMachines.size();             
                
                for(Machine machine: avMachines){  
                    for(int i=0;i<=numberProcess;i++){
                        /*
                         * Esto lo hizo camilo 
                         */
                        try{
                            //
                        }catch(Exception e){
                            //No importa
                        }
                    }
                }
            }
        } while (!tasklist.isEmpty());




    }
}